package main

import (
	"fmt"
)

// 定义一个HeroNode
type HeroNode struct {
	no int
	name string
	nickname string
	next *HeroNode // 这个表示指向下一个节点
}

// 给链表添加插入一个节点
// 编写第一种插入方式，在单链表的最后加入
func InsertHeroNode(head *HeroNode, newHeroNode *HeroNode) {
	// 思路
	// 1. 先找到该链表最后的节点

	// 2. 创建一个辅助节点
	temp := head
	for {
		if temp.next == nil { // 表示找到最后了
			break
		}
		temp = temp.next // 让temp不断的指向下一个节点
	}

	// 3. 将新节点加入到链表的最后
	temp.next = newHeroNode
}

// 编写第二种插入方式，根据no 的编号从小到大排序进行插入
func InsertHeroNode2(head *HeroNode, newHeroNode *HeroNode) {
	
	// 思路
	// 1. 找到适当的节点
	temp := head
	flag := true

	// 让插入的节点的no，和temp的下一个节点的no比较
	for {
		if temp.next == nil { // 说明到链表的最后了
			break
		} else if temp.next.no > newHeroNode.no {
			// 说明newHeroNode就应该插入到temp后面
			break
		} else if temp.next.no == newHeroNode.no {
			// 说明链表中已经有这个no，就不让插入
			flag = false
			break
		} 
		temp = temp.next
	}
	if !flag {
		fmt.Println("对不起，已经存在no：", newHeroNode.no)
		return
	} else {
		newHeroNode.next = temp.next
		temp.next = newHeroNode
	}
}

// 显示链表的所有节点信息
func ListHeroNode(head *HeroNode) {
	
	// 1. 创建一个辅助节点
	temp := head

	// 2. 先判断该链表是不是一个空链表
	if temp.next == nil {
		fmt.Println("链表是空的")
		return
	}

	// 3. 遍历这个链表
	for {
		fmt.Printf("[%d, %s, %s] -> ", temp.next.no, temp.next.name, temp.next.nickname)
		// 判断是否链表最后
		temp = temp.next
		if temp.next == nil {
			break
		}
	}
}

// 删除一个节点
func DelHeroNode(head *HeroNode, id int) {
	temp := head
	flag := false
	// 找到要删除的节点，和temp的下一个节点的no比较
	for {
		if temp.next == nil {
			break
		} else if temp.next.no == id {
			flag = true
			break
		}
		temp = temp.next
	}
	if flag { // 找到，删除
		temp.next = temp.next.next
	} else {
		fmt.Println("抱歉没有找到该节点")
	}
	fmt.Println()
}

func main() {

	// 1. 先创建一个头节点
	head := &HeroNode{}

	// 2. 创建一个新的节点
	hero1 := &HeroNode {
		no : 1,
		name : "宋江",
		nickname : "及时雨",
	}

	hero2 := &HeroNode {
		no : 2,
		name : "卢俊义",
		nickname : "玉麒麟",
	}

	hero3 := &HeroNode {
		no : 3,
		name: "林冲",
		nickname : "豹子头",
	}

	// 3. 加入
	InsertHeroNode2(head, hero2)
	InsertHeroNode2(head, hero1)
	InsertHeroNode2(head, hero3)

	// 4. 显示
	ListHeroNode(head)

	// 5. 删除
	DelHeroNode(head, 2)
	ListHeroNode(head)

}